package com.seari.custody.component;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.escape.Html4Unescape;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.XmlUtil;
import cn.hutool.crypto.SecureUtil;
import com.seari.custody.bean.Meeting;
import com.seari.custody.bean.MeetingDTO;
import com.seari.custody.exception.BIZException;
import lombok.extern.slf4j.Slf4j;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;

import javax.annotation.PostConstruct;
import javax.xml.xpath.XPathConstants;
import java.util.List;
import java.util.regex.Pattern;

@Component
@Slf4j
public class WebserviceClient {
    @Value("${wsdUrl}")
    public String wsdUrl;
    @Value("${keyCode}")
    public String keyCode;
    @Value("${adminPwd}")
    public String adminPwd;
    @Value("${userPassword}")
    private String userPassword;
    private Client client;


    @PostConstruct
    public void init() {

        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        client = dcf.createClient(wsdUrl);
//        client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME,PASS_WORD));
        HTTPConduit conduit = (HTTPConduit) client.getConduit();
        HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
        httpClientPolicy.setConnectionTimeout(2000);
        httpClientPolicy.setAllowChunking(false);
        httpClientPolicy.setReceiveTimeout(120000);
        conduit.setClient(httpClientPolicy);
        //client.getOutInterceptors().addAll(interceptors);

    }

    public String genKey() {
        return SecureUtil.md5(keyCode);
    }

    public List<MeetingDTO> getOnLineMeetings(String date) {


        return null;
    }


    /**
     * 创建会议
     *
     * @param meeting
     * @param meetingPwd
     * @return
     */
    public String createMeeting(Meeting meeting, String meetingPwd) {

        Integer roomId = 0;
        try {
            //支持汉字、英文字母a-zA-Z、数字0-9、英文下划线,长度在1-32位之间
            CharSequence replace1 = new Html4Unescape().replace(meeting.getMeetingHeadline());
            String meetingTitle = checkMeetingTitle(replace1.toString());

            String s = addRoominfo(meetingTitle, "2", meetingPwd, 50, "1", adminPwd, genKey());
            Document document = XmlUtil.parseXml(s);
            checkReturnStatus(document);
            roomId = Integer.parseInt(String.valueOf(XmlUtil.getByXPath("//room/roomId", document, XPathConstants.STRING)));
            String s1 = editRoomTypeToReservation(roomId, DateUtil.format(meeting.getStartTime(), DatePattern.NORM_DATETIME_PATTERN), DateUtil.format(meeting.getEndTime(), DatePattern.NORM_DATETIME_PATTERN), genKey());
            checkReturnStatus(XmlUtil.parseXml(s1));
//            String loginAddress = getLoginAddress(genKey());
//            System.out.println(loginAddress);
        } catch (Exception e) {
            throw new BIZException(e, "新增线上会议失败");
        }


        return String.valueOf(roomId);
    }


    /**
     * 获取会议室登录地址
     */
    public String getLoginAddress() {
        //调用时改为自己服务器地址端口
        String method = "getLoginAddress";

        Object[] object = {genKey()};
        Object[] res = new Object[0];
        try {
            res = client.invoke(method, object);
        } catch (Exception e) {
            throw new BIZException("获取会议登录地址失败", e);
        }
        String s = res[0].toString() + "";
        Document document = XmlUtil.parseXml(s);
        checkReturnStatus(document);
        return String.valueOf(XmlUtil.getByXPath("//data/nodeManAddr", document, XPathConstants.STRING));
    }

    /**
     * http://172.20.41.72:8080/launch/toEnterMeeting.do?pwdEncrypted=1&roomID=10663&userName=%E9%99%88%E9%A2%96&userPwd=qGz55jo4ZUVWJCVidKnOwQ==&roomPwd=1234&link=TCP:172.20.41.72:1089;TCP:172.20.41.76:1089;
     * 获得会议室信息
     *
     * @param roomId
     */
    public String getRoominfoList(String roomId) throws Exception {
        //调用时改为自己服务器地址端口
        String method = "getRoominfoList";

        Object[] object = {Integer.parseInt(roomId), "", "", 0, 10, genKey()};
        Object[] res = client.invoke(method, object);

        return res[0].toString() + "";
    }


    /**
     * 快捷添加会议室
     * （房间名、登录校验模型、会议室密码、允许最大用户数、是否允许管理员密码、管理员密码、密钥）
     *
     * @param roomName
     * @param verifyMode
     * @param password
     * @param maxUserCount
     * @param enableChairPwd
     * @param chairPassword
     * @param keyCode
     */
    public String addRoominfo(String roomName, String verifyMode, String password, Integer maxUserCount,
                              String enableChairPwd, String chairPassword, String keyCode) throws Exception {
        //调用时改为自己服务器地址端口
        String method = "addRoominfo";
        Object[] object = {roomName, verifyMode, password, maxUserCount, enableChairPwd, chairPassword, keyCode};
        Object[] res = client.invoke(method, object);
        return res[0].toString() + "";
    }


    /**
     * 修改会议室为预约会议室（会议室ID、预定开始时间、预定结束时间、密钥）
     *
     * @param roomId
     * @param hopeStartTime
     * @param hopeEndTime
     * @param keyCode
     */
    public String editRoomTypeToReservation(Integer roomId, String hopeStartTime, String hopeEndTime, String keyCode)
            throws Exception {
        //调用时改为自己服务器地址端口
        String method = "editRoomTypeToReservation";
        Object[] object = {roomId, hopeStartTime, hopeEndTime, keyCode};
        Object[] res = client.invoke(method, object);

        return res[0].toString() + "";
    }

    /**
     * 添加用户
     * 用户名、密码、昵称、组织架构、角色、性别、手机号、电话、邮箱、密钥、密码类型
     *
     * @param userName
     */
    public void addUserinfo(String userName)
            throws Exception {

        String method = "addUserinfo";

        Object[] object = {userName, userPassword, "", 0, "",
                "", "", "", "", genKey(), 0};
        Object[] res = client.invoke(method, object);
        String result = res[0].toString() + "";
        log.info(result);
        checkReturnStatus(XmlUtil.parseXml(result));
    }


    public void checkReturnStatus(Document document) {

        Object value = XmlUtil.getByXPath("//response/code", document, XPathConstants.STRING);
        Object message = XmlUtil.getByXPath("//response/message", document, XPathConstants.STRING);

        if (!"0000".equalsIgnoreCase(String.valueOf(value))) {
            throw new BIZException(String.valueOf(message));
        }
    }


    private String genPwd(int len) {
        String pwd = "";
        int[] ints = RandomUtil.randomInts(4);
        for (int anInt : ints) {
            pwd += anInt;
        }
        return pwd;
    }


    public static void main(String[] args) {

        String s = "唐镇新市镇C-11E-01地块临时用房";


        System.out.println(checkMeetingTitle(s));


    }

    private static String checkMeetingTitle(String s) {
        //支持汉字、英文字母a-zA-Z、数字0-9、英文下划线,长度在1-32位之间
        Pattern compile = Pattern.compile("^[\\u4e00-\\u9fa5_a-zA-Z0-9]+$");
        String[] split = s.split("");
        StringBuilder stringBuilder = new StringBuilder();
        for (String aChar : split) {
            if (compile.matcher(aChar).find()) {
                stringBuilder.append(aChar);
            }
        }
        return stringBuilder.toString();
    }
}
